#include "mainwindow.h"
#include "protreewidget.h"
#include "ui_mainwindow.h"

#include <QMenu>
#include <QAction>
#include <QDebug>
#include <QFileDialog>

#include "wizard.h"
#include "protree.h"
#include "protreewidget.h"

#include "./PicShow/picshow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    this->setMinimumSize(1629, 869); // 设置一个最小值
    ui->setupUi(this);


    // 创建菜单栏
    QMenu* menu_file = this->menuBar()->addMenu(tr("文件(&F)"));
    // 创建项目动作
    QAction* act_create_pro = new QAction(QIcon(":/icon/createpro.png"), tr("创建项目"), this);
    act_create_pro->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N)); // 创建快捷键
    menu_file->addAction(act_create_pro);
    // 打开项目动作
    QAction* act_open_pro = new QAction(QIcon(":/icon/openpro.png"), tr("打开项目"), this);
    act_open_pro->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O));
    menu_file->addAction(act_open_pro);

    // 创建设置菜单
    QMenu* menu_set = this->menuBar()->addMenu(tr("设置(&S)"));
    // 设置背景音乐
    QAction* act_music_pro = new QAction(QIcon(":/icon/music.png"), tr("背景音乐"), this);
    act_music_pro->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));
    menu_set->addAction(act_music_pro);

    // 注意下面的 &QAction::triggered 信号是会传递一个 bool 类型的变量的：void triggered(bool checked = false)，所以对应的槽函数也得有
    // 连接创建项目的槽函数
    connect(act_create_pro, &QAction::triggered, this, &MainWindow::SlotCreatePro);
    // 连接打开项目的槽函数
    connect(act_open_pro, &QAction::triggered, this, &MainWindow::SlotOpenPro);


    //// proLayout 的设置

    // 虽然 .h 头文件里面声明了 _protree 是一个 QWidget 类型的变量，但是 ProTree 的基类是 QDialog
    _protree = new ProTree();
    ui->proLayout->addWidget(_protree);

    // 因为 _protree 是 QWidget 类型，是 QTreeWidget 的基类，所以得 dynamic_cast 转化一下的哦
    QTreeWidget* tree_widget = dynamic_cast<ProTree*>(_protree)->GetTreeWidget();
    auto pro_tree_widget = dynamic_cast<ProTreeWidget*>(tree_widget);
    connect(this, &MainWindow::SigOpenPro, pro_tree_widget, &ProTreeWidget::SlotOpenPro);


    //// picLayout 的设置

    _picshow = new PicShow();
    ui->picLayout->addWidget(_picshow);

    // 为了不让 ProTree 类和 PicShow 类耦合(有头文件包含的情况)，MainWindow.h 里面正好包含了它们两个头文件，就可以在这个做一个连接了
    auto * pro_pic_show = dynamic_cast<PicShow*>(_picshow); // _picshow 是一个基类的指针类型，下面的 connect 函数需要一个原生的指针类型
    connect(pro_tree_widget, &ProTreeWidget::SigUpdateSelected, pro_pic_show, &PicShow::SlotSelectItem);

    // 前进后退按钮切换图片
    auto* pro_pro_tree = dynamic_cast<ProTree*>(_protree);
    // _picshow 从其页面接收 QPushButton 的 clicked 信号后，触发 pro_tree_widget 的槽函数
    // pro_tree_widget 的槽函数把处理后的，要显示图片路径再通过信号传递给 _picshow 的槽函数去 SlotUpdatePic
    connect(pro_pic_show, &PicShow::SigNextClicked, pro_tree_widget, &ProTreeWidget::SlotNextClicked);
    connect(pro_pic_show, &PicShow::SigPreClicked, pro_tree_widget, &ProTreeWidget::SlotPreClicked);
    connect(pro_tree_widget, &ProTreeWidget::SigUpdatePic, pro_pic_show, &PicShow::SlotUpdatePic); // 把处理好的，要显示的图片显示出来

    // 点击关闭的项目，正好是当前正在显示的项目 ---> 清空
    connect(pro_tree_widget, &ProTreeWidget::SigClearSelected, pro_pic_show, &PicShow::SlotClearSelected);

    // 设置音乐
    connect(act_music_pro, &QAction::triggered, pro_tree_widget, &ProTreeWidget::SlotSetMusic);
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 图像重绘
void MainWindow::resizeEvent(QResizeEvent *event)
{
    auto * pro_pic_show = dynamic_cast<PicShow*>(_picshow);
    pro_pic_show->ReloadPic(); // 重新加载

    return QMainWindow::resizeEvent(event); // 继续调用基类的虚函数
}

// void MainWindow::SlotCreatePro(bool){
void MainWindow::SlotCreatePro(bool checked){
    qDebug() << "slot create pro triggered" << Qt::endl;

    Wizard wizard(this);
    wizard.setWindowTitle(tr("创建项目"));
    auto* page = wizard.page(0);
    page->setTitle(tr("设置项目配置"));
    // 连接信号和槽，把项目配置传回来 todo......
    // 通过信号和槽，降低项目的耦合性
    // connect(&wizard, &Wizard::SigProSettings, _protree, &ProTree::AddProToTree);
    connect(&wizard, &Wizard::SigProSettings, dynamic_cast<ProTree*>(_protree), &ProTree::AddProToTree); // 把 _protree 安全转化一下
    // 流程：点击了菜单栏的创建项目，就会触发这个函数 -> next -> finshed -> &Wizard::SigProSettings -> Wizard::down -> emit SigProSettings(name, path) -> ProTree::AddProToTree(const QString name, const QString path) -> ProTreeWidget::AddProToTree(const QString &name, const QString &path)

    wizard.show();
    wizard.exec();
    // 断开所有的信号 todo......
    disconnect(&wizard);
}

// void MainWindow::SlotOpenPro(bool checked){
void MainWindow::SlotOpenPro(bool){
    QFileDialog file_dialog;
    file_dialog.setFileMode(QFileDialog::Directory);
    file_dialog.setWindowTitle(tr("选择导入的文件夹"));
    file_dialog.setDirectory(QDir::currentPath());
    file_dialog.setViewMode(QFileDialog::Detail); // 以详情的模式展示

    QStringList fileNames;
    if(file_dialog.exec()){
        fileNames = file_dialog.selectedFiles();
    }
    if(fileNames.length() <= 0){
        return ;
    }

    QString import_path = fileNames.at(0);
    emit SigOpenPro(import_path);
}
